﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using FarseerPhysics.Common;
using FarseerPhysics.Collision.Shapes;

namespace BHG.System
{
    public enum State
    {
        REMOVED, NORMAL
    }

    abstract class AbstractObject
    {
        public  State state = State.NORMAL;

        public virtual float Scale { get; set; }
        public Model Model { get; set; }
        public virtual float Rotation { get; set; }
        public virtual Vector2 Position { get; set; }
        public virtual float RotationY { get; set; }
        public virtual float RotationZ { get; set; }
        public virtual Vector3 Dislocation { get; set; }
        public virtual Vector3 RotationPerSecond { get; set; }
        public virtual Vector3 SpeedPerSecond { get; set; }
        public float Depth { get; set; }
        public float Life { get; set; }
        public Boolean Hide { get; set; }

        /* inheritance only */
        protected AbstractObject() { }

        public AbstractObject( Model model ):this(model,1f) {
        }

        public AbstractObject(Model model, float scale)
        {
            this.Scale = scale;
            this.Model = model;
            this.Dislocation = new Vector3(0f, 0f, 0f);
            this.RotationPerSecond = new Vector3(0f, 0f, 0f);
            this.SpeedPerSecond = new Vector3(0f, 0f, 0f);
            this.Life = -10;
            this.Depth = 0f;
            this.Hide = false;
        }

        public AbstractObject( Vector2 pos, float xRot, Model model ):this(pos,xRot,model,1f) {
        }

        public AbstractObject(Vector2 pos, float xRot, Model model, float scale):this(pos,xRot,model,scale,0f,0f)
        {
        }
        public AbstractObject(Vector2 pos, float xRot, Model model, float scale,float yRotation, float zRotation)
        {
            this.Model = model;
            this.Rotation = xRot;
            this.Position = pos;
            this.Scale = scale;
            this.RotationZ = yRotation;
            this.RotationY = zRotation;
            this.Dislocation = new Vector3(0f, 0f, 0f);
            this.RotationPerSecond = new Vector3(0f, 0f, 0f);
            this.SpeedPerSecond = new Vector3(0f, 0f, 0f);
            this.Life = -10;
            this.Depth = 0f;
            this.Hide = false;
        }

        public float DepthValue()
        {
            return Depth;
        }

        public virtual void Update( GameTime gameTime ) {
            float seconds = (float)gameTime.ElapsedGameTime.TotalSeconds;
            Rotation += RotationPerSecond.X * seconds;
            RotationY += RotationPerSecond.Y * seconds;
            RotationZ += RotationPerSecond.Z * seconds;

            Position = new Vector2(Position.X + SpeedPerSecond.X * seconds, Position.Y + SpeedPerSecond.Y * seconds);
            Depth += SpeedPerSecond.Z * seconds;

            if (this.Life != -10)
            {
                this.Life -= (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (this.Life < 0)
                {
                    this.state = State.REMOVED;
                }
            }
        }


        /// <summary>
        /// Do remove operation for object. Do not call directly, set state.Removed instead. Object will be removed on next game update.
        /// </summary>
        public virtual void doRemove() {
            this.state = State.REMOVED;
        }
    }
}
